function [PStar,ObjStar,Hess,Lmb] = myoptimize(ObjFn,X0,LB,UB,Opt,varargin)
% myoptimize  [Not a public function]
%
% Backend IRIS function.
% No help provided.

% -IRIS Toolbox.
% -Copyright (c) 2007-2015 IRIS Solutions Team.

%--------------------------------------------------------------------------

np = length(X0);
Hess = {zeros(np),zeros(np),zeros(np)};

if ischar(Opt.solver)
    % Optimization toolbox
    %----------------------
    if strncmpi(Opt.solver,'fmin',4)
        % Unconstrained minimization.
        if all(isinf(LB)) && all(isinf(UB))
            [PStar,ObjStar,~,~,~,Hess{1}] = ...
                fminunc(ObjFn,X0,Opt.optimset, ...
                varargin{:});
            Lmb = struct('lower',zeros(np,1),'upper',zeros(np,1));
        else
            % Constrained minimization.
            [PStar,ObjStar,~,~,Lmb,~,Hess{1}] = ...
                fmincon(ObjFn,X0, ...
                [],[],[],[],LB,UB,[],Opt.optimset,...
                varargin{:});
        end
    elseif strcmpi(Opt.solver,'lsqnonlin')
        % Nonlinear least squares.
        [PStar,ObjStar,~,~,~,Lmb] = ...
            lsqnonlin(ObjFn,X0,LB,UB,Opt.optimset, ...
            varargin{:});
    elseif strcmpi(Opt.solver,'pso')
        % IRIS Optimization Toolbox
        %--------------------------
        [PStar,ObjStar,~,~,~,~,Lmb] = ...
            irisoptim.pso(ObjFn,X0,LB,UB,...
            Opt.optimset{:},...
            varargin{:});
    elseif strcmpi(Opt.solver,'irismin')
        % IRIS Optimization Toolbox
        %--------------------------
        [PStar,ObjStar,Hess{1}] ...
            = irisoptim.irismin(ObjFn,X0,...
            Opt.optimset{:},varargin) ;
    elseif strcmpi(Opt.solver,'alps')
        % ALPS
        %--------------------------
        [PStar,ObjStar,Lmb] ...
            = irisoptim.alps(ObjFn,X0,LB,UB,...
            Opt.optimset{:}) ;
    end
else
    % User-supplied optimisation routine
    %------------------------------------
    if isa(Opt.solver,'function_handle')
        % User supplied function handle.
        f = Opt.solver;
        args = {};
    else
        % User supplied cell `{func,arg1,arg2,...}`.
        f = Opt.solver{1};
        args = Opt.solver(2:end);
    end
    [PStar,ObjStar,Hess{1}] = ...
        f(ObjFn, ...
        X0,LB,UB,Opt.optimset,args{:});
end
